package com.elitel.common.auth.service;

import com.alibaba.fastjson.JSONObject;
import com.elitel.common.auth.sysresource.cache.SysResourceCache;
import com.elitel.common.auth.sysresource.entity.SysResource;
import com.elitel.common.core.constant.SysUserConstant;
import com.elitel.common.core.domain.SysUserInfo;
import com.elitel.common.utils.HttpUtils;
import com.elitel.common.utils.ServletUtils;
import com.elitel.common.utils.StringUtils;
import com.elitel.common.utils.SysUserUtils;
import lombok.Setter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统用户服务类
 *
 * @author mulis
 */
@Setter
@ConfigurationProperties(prefix = "auth.login-user-filter")
@Component
@ConditionalOnMissingBean(SysUserService.class)
public class SysUserService {

    protected String url;

    protected boolean enabled;

    public SysUserInfo getUserInfoFromRemote(String verifyFieldValue) {
        // 有默认的实现，如果需要自定义实现，可以重写此方法
        SysUserInfo userInfo = new SysUserInfo();
        String resJson = HttpUtils.sendGet(url + "&loginName=" + verifyFieldValue);
        JSONObject jsonObject = JSONObject.parseObject(resJson);
        Object o = jsonObject.get("data");
        if (o instanceof Map) {
            Map oMap = (Map) o;
            userInfo.setAccount(oMap.get("loginName") + "");
            userInfo.setVerifyFiledVal(oMap.get("loginName") + "");
            Map<String, Object> prop = new HashMap<>();
            prop.put("tenantId", oMap.get("deptId"));
            userInfo.setExtendProp(prop);
            Object roleList = oMap.get("roleList");
            if (roleList instanceof List && !((List<?>) roleList).isEmpty()) {
                List list = (List) roleList;
                StringBuilder roleIds = new StringBuilder();
                for (Object object : list) {
                    if (object instanceof Map) {
                        Map map = (Map) object;
                        roleIds.append(map.get("roleId")).append(",");
                    }
                }
                userInfo.setRoleIds(roleIds.substring(0, roleIds.length() - 1));
            }

            // 获取并设置权限信息
            userInfo.setPermissions(getPermissions(userInfo));

        }
        return userInfo;
    }

    public boolean userExist() {
        // 获取缓存信息
        SysUserInfo userInfoFromSession = getUserInfo();
        if (userInfoFromSession != null) {
            return true;
        } else {
            // 从接口或者数据库获取用户信息
            String verifyFieldValue = SysUserUtils.getLoginAccount();
            SysUserInfo userInfo = getUserInfoFromRemote(verifyFieldValue);
            if (userInfo != null) {
                // 不为空，刷新缓存，并表示用户存在
                refreshWhitelist(userInfo);
                return true;
            } else {
                // 为空，返回用户不存在
                return false;
            }
        }
    }


    private String getPermissions(SysUserInfo userInfo) {
        // 获取用户所有角色
        String roleIds = userInfo.getRoleIds();
        HashSet<String> permissionSet = new HashSet<>();
        if (StringUtils.isNotEmpty(roleIds)) {
            String[] roleIdArr = roleIds.split(",");
            // 遍历角色
            for (String roleId : roleIdArr) {
                // 从缓存中获取角色的权限
                List<SysResource> permissionList = SysResourceCache.getPermissionList(roleId);
                if (permissionList != null && !permissionList.isEmpty()) {
                    Set<String> collect = permissionList.stream()
                            .map(SysResource::getPermission)
                            .filter(StringUtils::isNotEmpty)
                            .collect(Collectors.toSet());
                    permissionSet.addAll(collect);
                }
            }
        }
        return String.join(",", permissionSet);
    }

    public SysUserInfo getUserInfo() {
        HttpSession session = ServletUtils.getSession();
        String json = (String) session.getAttribute(SysUserConstant.LOGIN_USER_INFO);
        return JSONObject.parseObject(json, SysUserInfo.class);
    }


    void refreshWhitelist(SysUserInfo userInfo) {
        HttpSession session = ServletUtils.getSession();
        session.setAttribute(SysUserConstant.LOGIN_USER_INFO, JSONObject.toJSONString(userInfo));
    }
}
